﻿using DataService.Office.Word;
using DocumentFormat.OpenXml.Office.CustomXsn;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Data;
using DataService.Office.WordDTO;
using DataService.Office.Excel;

using DataService.Office.ExcelDTO;
using XmlCall;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Office2016.Excel;
using DocumentFormat.OpenXml.Drawing.Diagrams;
using DocumentFormat.OpenXml.Drawing.Wordprocessing;
using System.Drawing.Printing;
using DocumentFormat.OpenXml.Vml;







namespace DataService.Office.WordMain
{
    public class XmlPackageBussiness : IXmlPackageBussiness
    {
        private Dictionary<int, Stream> dic = new Dictionary<int, Stream>();
        public Body CreateBody(MainDocumentPart mainPart)
        {
            Body body = mainPart.Document.Body;
            return body;
        }
        public System.Xml.Linq.XDocument CreateStyleXml(MainDocumentPart mainPart)
        {
            System.Xml.Linq.XDocument xmlDocument = XmlPackagePart.WDExtractStyles(mainPart, false);
            return xmlDocument;
        }
        /// <summary>
        /// 获取纵向页尺寸
        /// </summary>
        /// <returns></returns>
        private PageSize GetPortraitPageSize()
        {
            var pageSize = new PageSize
            {
                Width = 11906U,
                Height = 16838U,
                Orient = PageOrientationValues.Portrait
            };
            return pageSize;
        }
        /// <summary>
        /// 纸张设置为纵向
        /// </summary>
        /// <param name="xmlElement"></param>
        public void SetPageOrientation(OpenXmlElement xmlElement)
        {
            //A4 纸的大小是 21cm x 29.7cm，为了展示表格美观 A4换成横向，1 厘米≈28.35磅
            //A4横向展示、设置纸张宽高, 横向：Landscape；纵向：Portrait
            var pageSize = GetPortraitPageSize();
            //xmlElement.AppendChild(sectionProperties);
            var sectPr = xmlElement.Descendants<SectionProperties>().ToList();
            if (sectPr.Count == 0)
            {
                SectionProperties sectionProperties = new SectionProperties(pageSize);
                xmlElement.AppendChild(sectionProperties);
            }
            else
            {
                sectPr[0].AddChild(pageSize);
            }
        }
        /// <summary>
        /// 横向页尺寸
        /// </summary>
        /// <returns></returns>
        private PageSize GetLandscapePageSize()
        {
            PageSize pageSize = new PageSize
            {
                Width = 16838U,
                Height = 11906U,
                Orient = PageOrientationValues.Landscape
            };
            return pageSize;
        }
        public void SetPageLandscape(OpenXmlElement xmlElement)
        {
            //A4 宽*高=11906*16838
            //A4 纸的大小是 21cm x 29.7cm，为了展示表格美观 A4换成横向，1 厘米≈28.35磅
            //A4横向展示、设置纸张宽高, 横向：Landscape；纵向：Portrait
            var pageSize = GetLandscapePageSize();
            var sectPr = xmlElement.Descendants<SectionProperties>().ToList();
            if (sectPr.Count == 0)
            {
                SectionProperties sectionProperties = new SectionProperties(pageSize);
                xmlElement.AppendChild(sectionProperties);
            }
            else
            {
                sectPr[0].AddChild(pageSize);
            }

        }
        private PageSize GetBodyPageSize(Body body)
        {
            PageSize sectprPageSize = null;
            var tempPageSize = body.Descendants<PageSize>();
            //  mainDocPart.DeleteParts(mainDocPart.HeaderParts);
            if (tempPageSize.Count() == 0)
            {
                sectprPageSize = GetPortraitPageSize();
            }
            else
            {
                sectprPageSize = tempPageSize.FirstOrDefault();
            }
            return sectprPageSize;
        }
        public Table TableAfterXmlElement(Body docBody, OpenXmlElement xmlElement)
        {
            //A4 纸的大小是 21cm x 29.7cm，为了展示表格美观 A4换成横向，1 厘米≈28.35磅
            //A4横向展示、设置纸张宽高, 横向：Landscape；纵向：Portrait
            //SectionProperties sectionProperties = new SectionProperties(new PageSize
            //{
            //    Width = 16838U,
            //    Height = 11906U,
            //    Orient = PageOrientationValues.Landscape
            //});
            //xmlElement.AppendChild(sectionProperties);

            return XmlTable.AfterParagraphTable(docBody, xmlElement);
        }


        public Table TableBeforeXmlElement(Body docBody, OpenXmlElement xmlElement)
        {
            return XmlTable.BeforeParagraphTable(docBody, xmlElement);
        }
        public Paragraph ParagraphAfterXmlElement(Body docBody, OpenXmlElement xmlElement)
        {
            return XmlParagraph.ParagraphAfterXmlElement(docBody, xmlElement);
        }


        public void AddTextTable(Table weekTable, DataTable dataTable, List<TableMergeCellDTO> cellMerge, List<TableVerticalMergeDTO> verticaMergeList, List<TableTextStyle> tableTextStyles)
        {
            XmlTable.AddTextTable(weekTable, dataTable, cellMerge, verticaMergeList, tableTextStyles);
        }
        public void AddTemplateDataTable(MainDocumentPart mainPart, Table tagertTable, List<WordTableDTO> wordTableDTOArray, WordAppendRowDTO wordAppendDataDTO)
        {
            XmlTable.EditTable(mainPart, tagertTable, wordTableDTOArray, wordAppendDataDTO);
        }


        public void AddImgTextTable(Table table, List<object[]> lstData, string[] headerArray)
        {
            XmlTable.AddImgTextTable(table, lstData, headerArray);
        }

        public void ParagraphAppendTitle(Paragraph paragraph, string text, int level)
        {
            if (level < 1 || level > 9)
                return;
            XmlPackageTitle.ParagraphAppendTitle(paragraph, text, level);
        }

        public OpenXmlElement AddImageToParagraph(MainDocumentPart mainPart, Paragraph paragraph, List<string> imgPathList)
        {
            decimal imgWidth = (decimal)10.2;
            decimal imgHeight = (decimal)5.93;
            return AddImageToParagraph(mainPart, paragraph, imgPathList, imgWidth, imgHeight);
        }

        public OpenXmlElement AddImageToParagraph(MainDocumentPart mainPart, Paragraph paragraph, List<string> imgPathList, decimal imgWidth, decimal imgHeight)
        {
            Body body = mainPart.Document.Body;
            foreach (var imgFileName in imgPathList)
            {
                ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
                using (FileStream stream = new FileStream(imgFileName, FileMode.Open))
                {
                    imagePart.FeedData(stream);
                }
                XmlToImg.AddImageToParagraph(paragraph, mainPart.GetIdOfPart(imagePart), imgWidth, imgHeight);
                paragraph = body.InsertAfter<Paragraph>(new Paragraph(), paragraph);
                paragraph = body.InsertAfter<Paragraph>(new Paragraph(), paragraph);
            }
            return paragraph;
        }
        public OpenXmlElement MulitipImgsToParagraph(MainDocumentPart mainPart, Paragraph paragraph, List<string> imgPathList, decimal imgWidth, decimal imgHeight)
        {
            Body body = mainPart.Document.Body;
            paragraph = body.InsertAfter<Paragraph>(new Paragraph(), paragraph);
            foreach (var imgFileName in imgPathList)
            {
                ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
                using (FileStream stream = new FileStream(imgFileName, FileMode.Open))
                {
                    imagePart.FeedData(stream);
                }
                XmlToImg.AddImageToParagraph(paragraph, mainPart.GetIdOfPart(imagePart), imgWidth, imgHeight);
            }
            return paragraph;
        }
        public OpenXmlElement AddImageToParagraph(MainDocumentPart mainPart, Paragraph paragraph, List<DrawingDTO> drawingDTOs)
        {
            Body body = mainPart.Document.Body;
            foreach (var imgDraw in drawingDTOs)
            {
                ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
                using (FileStream stream = new FileStream(imgDraw.AbsolutePath, FileMode.Open))
                {
                    imagePart.FeedData(stream);
                }
                XmlToImg.AddImageToParagraph(paragraph, mainPart.GetIdOfPart(imagePart), imgDraw.ShowWidth, imgDraw.ShowHeight);
                paragraph = body.InsertAfter<Paragraph>(new Paragraph(), paragraph);
                paragraph = body.InsertAfter<Paragraph>(new Paragraph(), paragraph);
            }
            return paragraph;
        }

        public OpenXmlElement AddImageToParagraph(MainDocumentPart mainPart, OpenXmlElement parentElement, Paragraph imgParagraph, List<DrawingDTO> drawingDTOs)
        {
            foreach (var imgDraw in drawingDTOs)
            {
                ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
                using (FileStream stream = new FileStream(imgDraw.AbsolutePath, FileMode.Open))
                {
                    imagePart.FeedData(stream);
                }
                XmlToImg.AddImageToParagraph(imgParagraph, mainPart.GetIdOfPart(imagePart), imgDraw.ShowWidth, imgDraw.ShowHeight);
                imgParagraph = parentElement.InsertAfter<Paragraph>(new Paragraph(), imgParagraph);
            }
            return imgParagraph;
        }

        public OpenXmlElement MulitipImgsToParagraph(MainDocumentPart mainPart, Paragraph paragraph, List<DrawingDTO> drawingDTOs)
        {
            Body body = mainPart.Document.Body;
            paragraph = body.InsertAfter<Paragraph>(new Paragraph(), paragraph);
            foreach (var itemImgDTO in drawingDTOs)
            {
                ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
                using (FileStream stream = new FileStream(itemImgDTO.AbsolutePath, FileMode.Open))
                {
                    imagePart.FeedData(stream);
                }
                XmlToImg.AddImageToParagraph(paragraph, mainPart.GetIdOfPart(imagePart), itemImgDTO.ShowWidth, itemImgDTO.ShowHeight);
            }
            return paragraph;
        }


        public void ParagraphAppendText(Paragraph paragraph, string text)
        {
            XmlBodyContent.ParagraphAppendText(paragraph, text);
        }

        private System.Xml.Linq.XDocument GetMainPartStyles(MainDocumentPart mainPart)
        {
            return XmlPackagePart.WDExtractStyles(mainPart, false);
        }
        public List<XmlTtitleDTO> GetXmlFirstTitles(MainDocumentPart mainPart)
        {
            List<XmlTtitleDTO> xmlTtitleDTOs = new List<XmlTtitleDTO>();
            Body body = mainPart.Document.Body;
            System.Xml.Linq.XDocument xmlDocument = GetMainPartStyles(mainPart);
            foreach (OpenXmlElement openXmlElement in body.ChildElements)
            {
                string currentTitle = XmlPackageTitle.GetGetWordTitleByHead(xmlDocument, openXmlElement, 1);
                if (!string.IsNullOrEmpty(currentTitle))
                {
                    xmlTtitleDTOs.Add(new XmlTtitleDTO { WordTitle = currentTitle, WordTitleLvl = 1 });
                }
            }
            return xmlTtitleDTOs;
        }
        public XmlElementDTO GetLastElementOfTitle(MainDocumentPart mainPart, string title, int titlelvl)
        {
            XmlElementDTO xmlElementDTO = new XmlElementDTO();
            Body body = mainPart.Document.Body;
            if (string.IsNullOrEmpty(title) || titlelvl == 0)
            {
                var newParagraph = body.AppendChild(new Paragraph());
                xmlElementDTO.Result = newParagraph;
                xmlElementDTO.ElementeLevel = 0;
                return xmlElementDTO;
            }
            System.Xml.Linq.XDocument xmlDocument = GetMainPartStyles(mainPart);
            OpenXmlElement currentLastElement = null;// title标题下的最后一个元素
            bool isFindLastParagraph = false;//是否找到需要插入数据的段落
            bool isFlag = false;//是否找到需要插入数据的段落
            foreach (OpenXmlElement openXmlElement in body.ChildElements)
            {
                if (openXmlElement is Table)
                {
                    currentLastElement = openXmlElement;
                    continue;
                }
                if (!isFlag)
                {
                    string currentTitle = XmlPackageTitle.GetGetWordTitleByHead(xmlDocument, openXmlElement, titlelvl);
                    if (!string.IsNullOrEmpty(currentTitle) && currentTitle == title)
                    {
                        isFlag = true;
                        continue;
                    }
                }
                //寻找当前标题的最后一个元素【最后一个元素可能是段落也可能是表格】。
                //1.例如当前标题是3级标题，则最后一个段落的的下一个标题。

                //1.1寻找下一个标题；可能是【2级标题、1级标题、文档的结尾元素】
                for (int k = titlelvl; k > 0; k--)
                {
                    string temptitle = XmlPackageTitle.GetGetWordTitleByHead(xmlDocument, openXmlElement, k);
                    if (!string.IsNullOrEmpty(temptitle) && isFlag)
                    {
                        //1.2找到了参照标题
                        isFindLastParagraph = true;
                        break;
                    }
                }
                if (isFindLastParagraph)
                {
                    break;
                }
                currentLastElement = openXmlElement;
            }
            if (currentLastElement == null)
            {
                currentLastElement = body.AppendChild(new Paragraph());
            }
            xmlElementDTO.Result = currentLastElement;
            xmlElementDTO.ElementeLevel = titlelvl;
            return xmlElementDTO;

        }
        public XmlElementDTO GetSonFirstElementOfTitle(MainDocumentPart mainPart, string title)
        {
            XmlElementDTO xmlElementDTO = new XmlElementDTO();
            Body body = mainPart.Document.Body;
            if (string.IsNullOrEmpty(title))
            {
                var newParagraph = body.AppendChild(new Paragraph());
                xmlElementDTO.Result = newParagraph;
                xmlElementDTO.ElementeLevel = 0;
                return xmlElementDTO;
            }
            System.Xml.Linq.XDocument xmlDocument = GetMainPartStyles(mainPart);
            OpenXmlElement currentLastElement = null;// title标题下的最后一个元素
            int currentTitleLvl = 0;// appnendData是几级标题
            bool isFindLastParagraph = false;//是否找到需要插入数据的段落
            foreach (OpenXmlElement openXmlElement in body.ChildElements)
            {
                currentLastElement = openXmlElement;
                if (openXmlElement is Table)
                {
                    continue;
                }
                for (int i = 1; i < 10; i++)
                {
                    string bodytitle = XmlPackageTitle.GetGetWordTitleByHead(xmlDocument, openXmlElement, i);
                    if (!string.IsNullOrEmpty(bodytitle) && currentTitleLvl > 0)
                    {
                        isFindLastParagraph = true;
                        break;
                    }
                    if (title == bodytitle)
                    {
                        currentTitleLvl = i;
                        break;
                    }
                }
                if (isFindLastParagraph)
                {
                    break;
                }
            }
            if (currentLastElement == null)
            {
                currentLastElement = body.AppendChild(new Paragraph());
            }
            xmlElementDTO.Result = currentLastElement;
            xmlElementDTO.ElementeLevel = currentTitleLvl;
            return xmlElementDTO;
        }
        public void Save(MainDocumentPart mainPart, List<int> newLevelList)
        {
            XmlPackageTitle.CreateDefinitionsPart(mainPart, newLevelList);
            mainPart.Document.Save();
        }

        public void Dispose(WordprocessingDocument wd)
        {
            int hashCode = wd.GetHashCode();
            wd.Dispose();
            if (dic != null && dic.Count > 0)
            {
                if (dic.ContainsKey(hashCode) && dic[hashCode] != null)
                {
                    dic[hashCode].Dispose();
                    dic.Remove(hashCode);
                }
            }
        }
        public List<Uri> GetPartWordFileUris(MainDocumentPart sourceMainDocumentPart)
        {
            List<Uri> uriList = new List<Uri>();
            var partList = sourceMainDocumentPart.Parts;
            foreach (var item in partList)
            {
                string tempRelativePath = item.OpenXmlPart.Uri.ToString();
                string relativeRoot = tempRelativePath.Split('/')[1];
                string extension = System.IO.Path.GetExtension(tempRelativePath);
                if (".docx".Equals(extension) && "word".Equals(relativeRoot))
                {
                    uriList.Add(item.OpenXmlPart.Uri);
                }
            }
            return uriList;
        }
        public WordprocessingDocument OpenUriDocument(WordprocessingDocument sourceWD, Uri uri)
        {
            var partList = sourceWD.MainDocumentPart.Parts;
            OpenXmlPart openXmlPart1 = null;
            foreach (var item in partList)
            {
                Uri tempRelativeUri = item.OpenXmlPart.Uri;
                if (tempRelativeUri == uri)
                {
                    openXmlPart1 = item.OpenXmlPart;
                    break;
                }
            }
            if (openXmlPart1 == null)
            {
                return null;
            }
            // PackagePart part = sourceWD.Package.GetPart(uri);
            Stream stream = openXmlPart1.GetStream();
            var wd = WordprocessingDocument.Open(stream, true);
            dic[wd.GetHashCode()] = stream;
            return wd;
        }
        public WordprocessingDocument CreateDocumentPart(string newFileName)
        {
            var wpdDocument = WordprocessingDocument.Create(newFileName, WordprocessingDocumentType.Document);
            MainDocumentPart mainPart = wpdDocument.AddMainDocumentPart();

            var docxDocument = new DocumentFormat.OpenXml.Wordprocessing.Document();
            mainPart.Document = docxDocument;
            mainPart.Document.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Body());
            return wpdDocument;
        }
        public WordprocessingDocument OpenDocumentPart(string filePath)
        {
            //需要判断文件大小，如果文件为0 需要创建，大于0则直接打开
            //2.判断文件大小
            var fileInfo = new FileInfo(filePath);
            WordprocessingDocument wd = null;
            if (fileInfo.Length == 0)
            {
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
                wd = CreateDocumentPart(filePath);
            }
            else
            {
                wd = WordprocessingDocument.Open(filePath, true);
            }
            return wd;
        }

        public void AddPageBreak(OpenXmlElement xmlElement)
        {
            XmlPageBreak.AddPageBreak(xmlElement);
        }
        public void AddNewPageBreak(OpenXmlElement xmlElement)
        {
            XmlPageBreak.AddNewPageBreak(xmlElement);
        }
        public bool MergeWordFiles(MainDocumentPart mainPart, List<string> sourcePaths, OpenXmlElement targetElement)
        {
            foreach (var itemPath in sourcePaths)
            {
                string altChunkId = "AltChunkId" + Guid.NewGuid().ToString().Replace("-", "");
                AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId);
                using (FileStream fileStream = File.Open(itemPath, FileMode.Open))
                {
                    chunk.FeedData(fileStream);
                    AltChunk altChunk = new AltChunk();
                    altChunk.Id = altChunkId;

                    targetElement = mainPart.Document.Body.InsertAfter(altChunk, targetElement);

                    ////var lastElement = mainPart.Document.Body.Descendants<Paragraph>().Last();
                    //if (mainPart.Document.Body.Elements().Count() > 1)
                    //{
                    //    // var lastElement = mainPart.Document.Body.Elements().Last();
                    //    mainPart.Document.Body.InsertAfter(altChunk, targetElement);
                    //    targetElement = mainPart.Document.Body.Elements().Last();
                    //}
                    //else
                    //{
                    //    mainPart.Document.Body.Append(altChunk);
                    //    targetElement = mainPart.Document.Body.Elements().Last();
                    //}
                }
            }
            return true;
        }
        public bool SetWordStyle(MainDocumentPart mainPart, Body body, Dictionary<int, XmlTextStyleDTO> titleStyleDic, XmlTextStyleDTO contentStyleDTO, XmlTextStyleDTO tableHeaderStyleDTO, XmlTextStyleDTO tableRowStyleDTO, XmlTextStyleDTO picStyleDTO, Action<string> action, CancellationTokenSource cts, AutoResetEvent are)
        {
            titleStyleDic = titleStyleDic ?? new Dictionary<int, XmlTextStyleDTO>();
            bool isSuccess = titleStyleDic.Keys.Any(x => x > 9 || x < 1);
            if (isSuccess)
            {
                throw new ArgumentException("参数错误");
            }
            bool isTableStyle = tableHeaderStyleDTO != null || tableRowStyleDTO != null;
            int tableNum = 0;
            System.Xml.Linq.XDocument xmlDocument = XmlPackagePart.WDExtractStyles(mainPart, false);
            bool isStart = false;
            foreach (OpenXmlElement openXmlElement in body.ChildElements)
            {
                if (cts.Token.IsCancellationRequested)
                {
                    are.Set(); //放行 Register 委托处的等待;
                    break;
                }
                if (!isStart)
                {
                    string firstTitle = XmlPackageTitle.GetGetWordTitleByHead(xmlDocument, openXmlElement, 1);
                    if (!string.IsNullOrEmpty(firstTitle))
                    {
                        isStart = true;
                    }
                }
                if (isStart)
                {
                    SetMainTileAndTextStyle(openXmlElement, xmlDocument, titleStyleDic, contentStyleDTO, action);
                    SetMainPicStyle(openXmlElement, picStyleDTO, action);
                    if ((openXmlElement is Table) && isTableStyle)
                    {
                        tableNum++;
                        XmlStyle.SetTableStyle(openXmlElement, tableHeaderStyleDTO, tableRowStyleDTO);
                        action($"表格{tableNum}");
                    }
                }
            }
            if (!isStart)
            {
                SetWordStyleAll(body, titleStyleDic, contentStyleDTO, tableHeaderStyleDTO, tableRowStyleDTO, picStyleDTO, action, cts, are, isTableStyle, xmlDocument);
            }
            return true;
        }
        private void SetWordStyleAll(Body body, Dictionary<int, XmlTextStyleDTO> titleStyleDic, XmlTextStyleDTO contentStyleDTO, XmlTextStyleDTO tableHeaderStyleDTO, XmlTextStyleDTO tableRowStyleDTO, XmlTextStyleDTO picStyleDTO, Action<string> action, CancellationTokenSource cts, AutoResetEvent are, bool isTableStyle, System.Xml.Linq.XDocument xmlDocument)
        {
            int tableNum = 0;
            foreach (OpenXmlElement openXmlElement in body.ChildElements)
            {
                if (cts.Token.IsCancellationRequested)
                {
                    are.Set(); //放行 Register 委托处的等待;
                    break;
                }
                SetMainTileAndTextStyle(openXmlElement, xmlDocument, titleStyleDic, contentStyleDTO, action);
                SetMainPicStyle(openXmlElement, picStyleDTO, action);
                if ((openXmlElement is Table) && isTableStyle)
                {
                    tableNum++;
                    XmlStyle.SetTableStyle(openXmlElement, tableHeaderStyleDTO, tableRowStyleDTO);
                    action($"表格{tableNum}");
                }
            }
        }
        public bool SetWordTableStyle(MainDocumentPart mainPart, Body body, XmlTextStyleDTO tableHeaderStyleDTO, XmlTextStyleDTO tableRowStyleDTO, Action<string> action, CancellationTokenSource cts, AutoResetEvent are)
        {
            int tableNum = 0;
            bool isTableStyle = tableHeaderStyleDTO != null || tableRowStyleDTO != null;
            foreach (OpenXmlElement openXmlElement in body.ChildElements)
            {
                if (cts.Token.IsCancellationRequested)
                {
                    are.Set(); //放行 Register 委托处的等待;
                    break;
                }
                if ((openXmlElement is Table) && isTableStyle)
                {
                    tableNum++;
                    XmlStyle.SetTableStyle(openXmlElement, tableHeaderStyleDTO, tableRowStyleDTO);
                    action($"表格{tableNum}");
                }
            }
            return true;
        }

        public bool SetWordTileAndTextStyle(MainDocumentPart mainPart, Body body, Dictionary<int, XmlTextStyleDTO> titleStyleDic, XmlTextStyleDTO contentStyleDTO, Action<string> action, CancellationTokenSource cts, AutoResetEvent are)
        {
            titleStyleDic = titleStyleDic ?? new Dictionary<int, XmlTextStyleDTO>();
            bool isSuccess = titleStyleDic.Keys.Any(x => x > 9 || x < 1);
            if (isSuccess)
            {
                throw new ArgumentException("参数错误");
            }
            System.Xml.Linq.XDocument xmlDocument = XmlPackagePart.WDExtractStyles(mainPart, false);
            bool isStart = false;//寻找第一个一级标题

            foreach (OpenXmlElement openXmlElement in body.ChildElements)
            {
                if (cts.Token.IsCancellationRequested)
                {
                    are.Set();
                    break;
                }
                if (!isStart)
                {
                    string firstTitle = XmlPackageTitle.GetGetWordTitleByHead(xmlDocument, openXmlElement, 1);
                    if (!string.IsNullOrEmpty(firstTitle))
                    {
                        isStart = true;
                    }
                }
                if (isStart)
                {
                    SetMainTileAndTextStyle(openXmlElement, xmlDocument, titleStyleDic, contentStyleDTO, action);
                }
            }
            if (!isStart)
            {
                SetWordTileAndTextStyleAll(body, titleStyleDic, contentStyleDTO, action, cts, are, xmlDocument);
            }
            return true;
        }
        private void SetWordTileAndTextStyleAll(Body body, Dictionary<int, XmlTextStyleDTO> titleStyleDic, XmlTextStyleDTO contentStyleDTO, Action<string> action, CancellationTokenSource cts, AutoResetEvent are, System.Xml.Linq.XDocument xmlDocument)
        {
            foreach (OpenXmlElement openXmlElement in body.ChildElements)
            {
                if (cts.Token.IsCancellationRequested)
                {
                    are.Set();
                    break;
                }
                SetMainTileAndTextStyle(openXmlElement, xmlDocument, titleStyleDic, contentStyleDTO, action);

            }
        }
        private bool SetMainTileAndTextStyle(OpenXmlElement openXmlElement, System.Xml.Linq.XDocument xmlDocument, Dictionary<int, XmlTextStyleDTO> titleStyleDic, XmlTextStyleDTO contentStyleDTO, Action<string> action)
        {
            if (openXmlElement is Paragraph)
            {
                XmlTextStyleDTO titleStyle = null;
                Paragraph paragraph = openXmlElement as Paragraph;
                string temptitle = string.Empty;
                var pTexts = XmlParagraph.GetParagraphText(openXmlElement);
                if (!string.IsNullOrEmpty(pTexts))
                {
                    foreach (var item in titleStyleDic)
                    {
                        temptitle = XmlPackageTitle.GetGetWordTitleByHead(xmlDocument, openXmlElement, item.Key);
                        if (!string.IsNullOrEmpty(temptitle))
                        {
                            titleStyle = item.Value;
                            break;
                        }
                    }
                    if (titleStyle != null)
                    {
                        //标题
                        XmlStyle.SetBodyContentStyle(paragraph, titleStyle);
                        action($"标题-{temptitle}");
                    }
                    if (!string.IsNullOrEmpty(pTexts) && string.IsNullOrEmpty(temptitle) && contentStyleDTO != null)
                    {
                        //正文
                        XmlStyle.SetBodyContentStyle(paragraph, contentStyleDTO);

                        if (!string.IsNullOrEmpty(pTexts) && pTexts.Length > 55)
                        {
                            pTexts = pTexts.Substring(0, 55) + "...";
                        }
                        action($"正文-{pTexts}");
                    }
                }
            }
            return true;
        }
        public bool SetWordPicStyle(MainDocumentPart mainPart, Body body, XmlTextStyleDTO picStyleDTO, Action<string> action, CancellationTokenSource cts, AutoResetEvent are)
        {
            foreach (OpenXmlElement openXmlElement in body.ChildElements)
            {
                if (cts.Token.IsCancellationRequested)
                {
                    are.Set();
                    break;
                }
                SetMainPicStyle(openXmlElement, picStyleDTO, action);
            }
            return true;
        }

        private bool SetMainPicStyle(OpenXmlElement openXmlElement, XmlTextStyleDTO picStyleDTO, Action<string> action)
        {
            if (openXmlElement is Paragraph)
            {
                Paragraph paragraph = openXmlElement as Paragraph;
                // var pTexts = XmlParagraph.GetParagraphText(openXmlElement);
                //不是文本
                //插图排版
                var tempDrawings = openXmlElement.Descendants<Drawing>();
                if (tempDrawings.Count() > 0)
                {
                    List<string> imgNames = new List<string>();
                    foreach (Drawing itemDrawing in tempDrawings)
                    {
                        var tempInlines = itemDrawing.Descendants<DocumentFormat.OpenXml.Drawing.Wordprocessing.Inline>();
                        foreach (var itemInLine in tempInlines)
                        {
                            if (itemInLine.DocProperties != null)
                            {
                                imgNames.Add(itemInLine.DocProperties.Name);
                            }
                        }
                    }
                    if (imgNames.Count > 0)
                    {
                        XmlStyle.SetBodyContentStyle(paragraph, picStyleDTO);
                        foreach (string itempicName in imgNames)
                        {
                            action($"插图-{itempicName}");
                        }
                    }
                }
            }
            return true;
        }


        public bool WordInExcel(string wordFullPath, string excelFullPath, List<ExcelToWordParmDTO> excelToWordParmDTOs, string paramHeader, string paramFooter)
        {
            bool isTempFile = false;
            WordprocessingDocument wd = null;
            bool isBreak = false;
            bool isEmptyDoc = false;
            if (File.Exists(wordFullPath))
            {
                wd = OpenDocumentPart(wordFullPath);
                isTempFile = true;

            }
            else
            {
                wd = CreateDocumentPart(wordFullPath);
            }
            MainDocumentPart md = wd.MainDocumentPart;
            Body body = md.Document.Body;
            if (isTempFile)
            {
                isBreak = DataService.Office.Word.XmlPageBreak.LastElementIsSectionBreak(body);
                isEmptyDoc = XmlBodyContent.IsDocumentEmpty(body);
            }
            if (excelToWordParmDTOs == null || excelToWordParmDTOs.Count == 0)
            {
                throw new ArgumentNullException("参数不能为空");
            }



            //// 获取或创建节属性
            //SectionProperties sectionProperties = body.Descendants<SectionProperties>().FirstOrDefault();
            //if (sectionProperties == null)
            //{
            //    sectionProperties = new SectionProperties();
            //    body.AppendChild(sectionProperties);
            //}
            //sectionProperties.Append(new PageSize()
            //{
            //    Width = 16838U, // 将英寸转换为EMU
            //    Height = 11906U, // 将英寸转换为EMU
            //    Orient = PageOrientationValues.Landscape,
            //});



            List<int> levelList = new List<int>();
            string pattern = @"\d+";
            try
            {
                using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(excelFullPath, false))
                {
                    DocumentFormat.OpenXml.Packaging.WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
                    DocumentFormat.OpenXml.Spreadsheet.CellFormats cellFormats = ExcelHepler.GetCellFormat(workbookPart);
                    DocumentFormat.OpenXml.Spreadsheet.Stylesheet stylesheet = ExcelHepler.GetStylesheet(workbookPart);
                    ThemePart themePart = workbookPart.ThemePart;
                    //获取spreadsheetDocument中共享的数据
                    DocumentFormat.OpenXml.Spreadsheet.SharedStringTable stringTable = workbookPart.SharedStringTablePart.SharedStringTable;

                    //  DocumentFormat.OpenXml.Spreadsheet.SharedStringTable stringTable=   workbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();

                    int totalCount = excelToWordParmDTOs.Count;
                    int tempSheetNum = 0;
                    foreach (var itemSheet in excelToWordParmDTOs)
                    {

                        tempSheetNum++;
                        DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = ExcelHepler.SeekSheet(workbookPart, itemSheet.SheetName);
                        WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
                        DocumentFormat.OpenXml.Spreadsheet.Worksheet worksheet = worksheetPart.Worksheet;
                        var sheetData = worksheet.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.SheetData>();
                        OpenXmlElement currentElement = null;
                        currentElement = body.AppendChild<Paragraph>(new Paragraph());



                        if (isTempFile && tempSheetNum == 1)
                        {
                            if (!isBreak && !isEmptyDoc)
                            {
                                currentElement = ParagraphAfterXmlElement(body, currentElement);
                                //  AddPageBreak(currentElement);
                            }
                        }
                        if (tempSheetNum == 1)
                        {
                            SetPageLandscape(body);
                        }


                        string sheetName = itemSheet.SheetName;
                        currentElement = ParagraphAfterXmlElement(body, currentElement);
                        var currentParagrph = currentElement as Paragraph;
                        // ParagraphAppendTitle(currentParagrph, sheetName, 1);
                        Text runtxt = new Text();
                        runtxt.Text = sheetName;
                        Run titleRun = currentParagrph.AppendChild(new Run());
                        titleRun.Append(runtxt);
                        XmlTextStyleDTO xmlTextStyleDTO = new XmlTextStyleDTO
                        {
                            Algin = Algin.Center,
                            FontBold = true,
                            FontFamilysEnum = FontFamilysEnum.宋体
                        };
                        XmlStyle.SetBodyContentStyle(currentParagrph, xmlTextStyleDTO);

                        levelList.Add(1);



                        DocumentFormat.OpenXml.Wordprocessing.Table wordTable = TableAfterXmlElement(body, currentElement);



                        wordTable.AppendChild(XmlTable.ReturnTableProperties("4F81BD", 1));

                        List<string> paramCells = itemSheet.CellPostions;
                        if (paramCells != null && paramCells.Count > 0)
                        {
                            for (int i = 0; i < paramCells.Count; i++)
                            {
                                paramCells[i] = Regex.Replace(paramCells[i], pattern, "");
                            }

                        }


                        #region word table 设置

                        #region 获取excel参数
                        int sheetCellCount = itemSheet.EffectiveCellNum;
                        //foreach (var itemRow in sheetData.Descendants<DocumentFormat.OpenXml.Spreadsheet.Row>())
                        //{
                        //    foreach (DocumentFormat.OpenXml.Spreadsheet.Cell sheetCell in itemRow.Elements<DocumentFormat.OpenXml.Spreadsheet.Cell>())
                        //    {
                        //        //1.如果指定列为空，则默认将所有列写入word，2.如果指定的列不为空，则只将指定的列写入word
                        //        if (paramCells != null && paramCells.Count > 0)
                        //        {
                        //            string cellPostion = sheetCell.CellReference;
                        //            string newCellPostion = Regex.Replace(cellPostion, pattern, "");
                        //            if (!paramCells.Any(x => x == newCellPostion))
                        //            {
                        //                continue;
                        //            }
                        //        }
                        //        sheetCellCount++;
                        //    }
                        //    if (sheetCellCount == 0)
                        //    {
                        //        sheetCellCount = itemSheet.EffectiveCellNum;
                        //    }

                        //    break;
                        //}


                        List<string> colNames = new List<string>();
                        for (int n = 1; n <= itemSheet.EffectiveCellNum; n++)
                        {
                            colNames.Add(ExcelHepler.ColToA1(n));
                        }
                        #region 获取Excel合并列
                        var mergerDTOs = ExcelHepler.GetMergeCells(worksheet);
                        #endregion


                        #endregion

                        List<string> columnNameList = new List<string>();


                        int tempParamCount = sheetCellCount;
                        WriteLine($"tempParamCount：{tempParamCount}");

                        int tempWidthRat = 100 / tempParamCount;

                        string tableCellWidth = $"{tempWidthRat}%";


                        #endregion

                        List<WordRowDTO> wordRowDTOs = new List<WordRowDTO>();
                        Dictionary<int, List<string>> rowCellVals = new Dictionary<int, List<string>>();
                        int tempRowCount = worksheet.Descendants<DocumentFormat.OpenXml.Spreadsheet.Row>().Count();
                        if (tempRowCount > 0)
                        {
                            int rowIndex = 0;

                            // 遍历Excel工作表中的单元格并将它们添加到Word表格中
                            foreach (DocumentFormat.OpenXml.Spreadsheet.Row sheetRow in sheetData.Descendants<DocumentFormat.OpenXml.Spreadsheet.Row>())
                            {
                                rowIndex++;
                                bool isWordTableTitle = rowIndex <= itemSheet.HeadRowNum;
                                TableRow wordTableRow = new TableRow();
                                bool isHaveVal = false;
                                int cellIndex = 0;
                                int yxCounter = 0;
                                // List<ExcelRowCell> cellVals = new List<ExcelRowCell>();

                                //获取 该行 的所有列 值
                                List<ExcelRowCell> excelRowCells = ExcelHepler.GetRowCellValues(colNames, sheetRow, workbookPart, stringTable);

                                foreach (ExcelRowCell itemExcelRowCell in excelRowCells)
                                {
                                    cellIndex++;

                                    string cellPostion = itemExcelRowCell.CellReference;
                                    //1.如果指定列为空，则默认将所有列写入word，2.如果指定的列不为空，则只将指定的列写入word
                                    if (paramCells != null && paramCells.Count > 0)
                                    {
                                        string newCellPostion = Regex.Replace(cellPostion, pattern, "");
                                        if (!paramCells.Any(x => x == newCellPostion))
                                        {
                                            continue;
                                        }
                                    }
                                    yxCounter++;
                                    if (isWordTableTitle)
                                    {
                                        string tempExcelCol = Regex.Replace(cellPostion, pattern, "");

                                        ExcelHepler.CellReferenceToRowAndColumn(cellPostion, out int endRow, out int endCol);
                                        wordRowDTOs.Add(new WordRowDTO
                                        {
                                            WordRowIndex = rowIndex,
                                            WordColumnIndex = yxCounter,
                                            ExcelCellReference = cellPostion,
                                            ExcelCellCol = tempExcelCol,
                                            ExcelCellPotion_RowIndex = endRow,
                                            ExcelCellPotion_ColIndex = endCol
                                        });
                                    }
                                    //uint cellStyleIndex = sheetCell.StyleIndex?.Value ?? 0;
                                    ExcelRowCellStyleDTO cellStyleDTO = new ExcelRowCellStyleDTO();
                                    var tempCell = itemExcelRowCell.Cell;
                                    if (tempCell != null)
                                    {
                                        cellStyleDTO = ExcelHepler.GetCellFont(cellFormats, stylesheet, themePart, tempCell);
                                    }




                                    DocumentFormat.OpenXml.Wordprocessing.TableCell wordTableCell = wordTableRow.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.TableCell());
                                    var tableWidth = new TableCellWidth { Width = tableCellWidth, Type = TableWidthUnitValues.Pct };



                                    TableCellProperties tabCellProps = new TableCellProperties(tableWidth);




                                    TableCellVerticalAlignment tableCellVerticalAlignment = new TableCellVerticalAlignment { Val = TableVerticalAlignmentValues.Center };

                                    tabCellProps.Append(tableCellVerticalAlignment);

                                    var tcpr = wordTableCell.AppendChild(tabCellProps);



                                    Paragraph tabCellPara = wordTableCell.AppendChild(new Paragraph());

                                    Justification justification = new Justification() { Val = JustificationValues.Center };
                                    ParagraphProperties paragraphProperties = new ParagraphProperties();
                                    paragraphProperties.Append(justification);
                                    tabCellPara.Append(paragraphProperties);
                                    string vale = itemExcelRowCell.Value;
                                    //  string vale = ExcelHepler.GetCellValue(sheetCell, workbookPart, stringTable);
                                    if (string.IsNullOrEmpty(vale))
                                    {
                                        vale = "";
                                    }
                                    ExcelHepler.CellReferenceToRowAndColumn(cellPostion, out int currRow, out int currCol);
                                    string currCellPostionCol = Regex.Replace(cellPostion, pattern, "");
                                    ExcelRowCell excelRowCellDTO = new ExcelRowCell();
                                    excelRowCellDTO.CellReference = cellPostion;
                                    excelRowCellDTO.CellReferenceCol = currCellPostionCol;
                                    excelRowCellDTO.RowIndex = currRow;
                                    excelRowCellDTO.ColumnIndex = currCol;
                                    excelRowCellDTO.Value = vale;

                                    // cellVals.Add(excelRowCellDTO);


                                    var wordCellRun = new DocumentFormat.OpenXml.Wordprocessing.Run();

                                    var wordrunProperties = wordCellRun.RunProperties;
                                    if (wordrunProperties == null)
                                    {
                                        wordrunProperties = wordCellRun.AppendChild(new RunProperties());
                                    }

                                    float tempBangZhi = XmlStyle.GetWordBang(FontSizeEnum.小五);
                                    FontSize fontSize = wordrunProperties.FontSize;
                                    if (fontSize == null)
                                    {
                                        fontSize = new FontSize();

                                    }
                                    fontSize.Val = (tempBangZhi * 2).ToString();
                                    wordrunProperties.Append(fontSize);


                                    RunFonts runFonts = wordrunProperties.RunFonts;
                                    if (runFonts == null)
                                    {
                                        runFonts = new RunFonts();
                                    }
                                    string fontName = FontFamilysEnum.宋体.ToString();
                                    runFonts.Ascii = fontName;
                                    runFonts.HighAnsi = fontName;
                                    runFonts.EastAsia = fontName;
                                    wordrunProperties.Append(runFonts);



                                    if (!string.IsNullOrEmpty(cellStyleDTO.ColorName))
                                    {
                                        string hx16Color = cellStyleDTO.ColorName.Replace("#", "");
                                        Color color = new Color() { Val = hx16Color }; // 颜色
                                        wordrunProperties.Color = color;
                                    }
                                    if (!string.IsNullOrEmpty(cellStyleDTO.BackColorName))
                                    {
                                        Shading shd = tabCellProps.GetFirstChild<Shading>();
                                        if (shd == null)
                                        {
                                            shd = new Shading();
                                            tabCellProps.AppendChild<Shading>(shd);
                                        }
                                        string hx16Color = cellStyleDTO.BackColorName.Replace("#", "");
                                        // 设置背景颜色和 transparency
                                        shd.Val = ShadingPatternValues.Clear;
                                        shd.Color = "auto";
                                        shd.Fill = hx16Color;
                                    }
                                    if (cellStyleDTO.FontBold || isWordTableTitle)
                                    {
                                        var tempRunProperties = wordCellRun.RunProperties;
                                        if (tempRunProperties == null)
                                        {
                                            tempRunProperties = wordCellRun.AppendChild(new RunProperties());
                                        }
                                        Bold bold2 = new Bold();
                                        tempRunProperties.Bold = bold2;
                                    }


                                    if (!string.IsNullOrWhiteSpace(vale) && !string.IsNullOrEmpty(vale) && vale.Length > 0)
                                    {
                                        wordCellRun.Append(new DocumentFormat.OpenXml.Wordprocessing.Text(vale));
                                        tabCellPara.Append(wordCellRun);
                                        isHaveVal = true;
                                    }
                                    else
                                    {
                                        wordCellRun.Append(new DocumentFormat.OpenXml.Wordprocessing.Text(vale));
                                        tabCellPara.Append(wordCellRun);
                                    }
                                }


                                if (isHaveVal && cellIndex > 0 && cellIndex < sheetCellCount)
                                {
                                    XmlTable.RowAppendCell(wordTableRow, tableCellWidth);
                                }

                                if (isHaveVal)
                                {
                                    #region 解决跨页断行问题

                                    XmlTable.RowCantSplit(ref wordTableRow);

                                    //DocumentFormat.OpenXml.Wordprocessing.TableRowProperties tableRowProperties = new TableRowProperties();
                                    //tableRowProperties.Append(new GridAfter { Val = 1 });

                                    //CantSplit cantSplit = new CantSplit() { Val = OnOffOnlyValues.On };
                                    //tableRowProperties.Append(cantSplit);

                                    //var rowJustification = new DocumentFormat.OpenXml.Wordprocessing.Justification { Val = JustificationValues.Center };
                                    //tableRowProperties.Append(rowJustification);

                                    //wordTableRow.Append(tableRowProperties);

                                    #endregion
                                    wordTable.AppendChild(wordTableRow);
                                }

                                //  rowCellVals[rowIndex] = cellVals;
                            }

                            if (tempSheetNum < excelToWordParmDTOs.Count)
                            {
                                //分节符，添加后，模板上的页眉页脚不显示，现要求，不需要加分节符
                                // var newParagraph = XmlParagraph.ParagraphAfterXmlElement(body, wordTable);
                                //AddPageBreak(newParagraph);
                                // SetPageLandscape(newParagraph);
                            }
                            md.Document.Save();

                        }
                        else
                        {
                            if (tempSheetNum < excelToWordParmDTOs.Count)
                            {
                                // var newParagraph = body.AppendChild<Paragraph>(new Paragraph());

                                // AddPageBreak(newParagraph);

                                // SetPageLandscape(newParagraph);
                            }

                        }

                        if (tempSheetNum == excelToWordParmDTOs.Count)
                        {
                            //最后一节设置为横向展示，分节之后，最后一页添加分节符，会多出一个空白页
                            //空白页解决办法，最后一个不添加分节符，在此处设置body或者  新创建锻炼的横向展示
                            // //SetPageLandscape(body);
                        }

                        if (itemSheet.HeadRowNum == 1)
                        {

                        }
                        if (itemSheet.HeadRowNum == 2 || itemSheet.HeadRowNum == 3)
                        {
                            MegerWordTable(wordTable, mergerDTOs, wordRowDTOs, itemSheet.HeadRowNum);
                        }


                    }


                }
                // var pageSize = GetBodyPageSize(body);
                levelList = levelList.Distinct().ToList();
                if (!string.IsNullOrEmpty(paramHeader))
                {
                    string heaerText = XmlHeaderFooter.GetHeadText(md);
                    if (!string.IsNullOrEmpty(heaerText))
                    {
                        if (heaerText != paramHeader)
                        {
                            XmlHeaderFooter.ModifyHeaderText(md, heaerText, paramHeader);
                        }
                    }
                    else
                    {

                        HeaderPart headerPart = XmlHeaderFooter.AddHeader(md, paramHeader);
                        AddHeadFootWaterMaskRelation(md, headerPart);
                    }
                }
                if (!string.IsNullOrEmpty(paramFooter))
                {
                    string footerText = XmlHeaderFooter.GetFootText(md);
                    if (!string.IsNullOrEmpty(footerText))
                    {
                        if (footerText != paramFooter)
                        {
                            XmlHeaderFooter.ModifyFooterText(md, footerText, paramFooter);
                        }
                    }
                    else
                    {
                        FooterPart footerPart = XmlHeaderFooter.AddFooter(md, paramFooter);
                        AddHeadFootWaterMaskRelation(md, footerPart);
                    }

                }
                //bool isPageNum = DataService.Office.Word.WordPageNum.IsPageNum(md, body);
                //if (!isPageNum)
                //{
                //    WordPageNum.SetPageNum(md, body);
                //}
                //修改为 使用模板不添加连续页码
                if (!isTempFile)
                {
                    WordPageNum.SetPageNum(md, body);
                }
            }
            catch (Exception ex)
            {
                WriteLine(ex.StackTrace + "***" + ex.Message + "***" + ex.InnerException);
                throw ex;
            }
            finally
            {
                //因为不需要设置标题
                levelList = new List<int>();
                Save(md, levelList);
                wd.Dispose();
            }
            return true;

        }

        /// <summary>
        /// 合并 word表格 表头
        /// </summary>
        private void MegerWordTable(DocumentFormat.OpenXml.Wordprocessing.Table wordTable, List<ExcelRowParamDTO> mergerDTOs, List<WordRowDTO> wordRowDTOs, int excelHeadRowNum)
        {
            try
            {
                int defaultHeadNum = 3; //默认几行表头
                var tempWordTableRows = wordTable.Descendants<DocumentFormat.OpenXml.Wordprocessing.TableRow>();
                int wordHeadNum = 0;
                for (int i = 0; i < defaultHeadNum; i++)
                {
                    var tempRow = tempWordTableRows.ElementAt(i);
                    bool isTitle = IsTableTitle(tempRow);
                    if (isTitle)
                    {
                        wordHeadNum++;
                    }
                    else
                    {
                        break;
                    }
                }


                foreach (var itemExcelMerger in mergerDTOs)
                {
                    //纵向合并
                    if (itemExcelMerger.Direction == MegerDirectionEnum.纵向合并)
                    {
                        // A1: A3 ；B1:B2 纵向合并
                        List<WordRowDTO> tempWordRowDTOs = wordRowDTOs.Where(x => x.ExcelCellCol == itemExcelMerger.StartPotionCol).ToList();
                        if (tempWordRowDTOs != null && tempWordRowDTOs.Count > 0)
                        {
                            int tempWordTableCol = tempWordRowDTOs[0].WordColumnIndex;


                            int startWordTableRow = itemExcelMerger.StartPotion_RowIndex;
                            int endWordTableRow = itemExcelMerger.EndPotion_RowIndex;


                            //开始 行和列
                            var tempStartRow = tempWordTableRows.ElementAt(startWordTableRow - 1);
                            if (startWordTableRow >= wordHeadNum)
                            {
                                continue;
                            }
                            var tempStartRowCell = tempStartRow.Descendants<TableCell>().ElementAt(tempWordTableCol - 1);

                            //结束 行和列
                            var tempEndRow = tempWordTableRows.ElementAt(endWordTableRow - 1);
                            if (endWordTableRow <= wordHeadNum)
                            {

                                var tempEndRowCell = tempEndRow.Descendants<TableCell>().ElementAt(tempWordTableCol - 1);

                                if (tempStartRowCell != null && tempEndRowCell != null)
                                {
                                    XmlTable.SetVerticalMerge(tempStartRowCell, MergedCellValues.Restart);
                                    XmlTable.SetVerticalMerge(tempEndRowCell, MergedCellValues.Continue);
                                }
                            }
                        }
                    }
                    //横向合并
                    if (itemExcelMerger.Direction == MegerDirectionEnum.横向合并)
                    {
                        //C1:D1   
                        //寻找开始的 行和列
                        int start_RowIndex = itemExcelMerger.StartPotion_RowIndex;
                        int start_ColInx = itemExcelMerger.StartPotion_ColIndex;

                        int end_RowIndex = itemExcelMerger.EndPotion_RowIndex;
                        int end_ColInx = itemExcelMerger.EndPotion_ColIndex;

                        //假设，Excel 横向合并位置 B2:F2
                        //情况一:没有B2到 F2的列, 即 没有Excel中的第2列 至第6列
                        //情况二: 横向合并位置 B2:F2，只有B2、D2 、E2、F2等 一个单元格
                        //情况三：横向合并位置 B2:F2（列2：列6），word中 B2:C2 或 B2:D2 或 C2:E2等
                        //情况四：B2:G2 、D2:AU2
                        //情况五：B2:F2

                        //excel横向合并的列数量
                        int excelMergerNum = end_ColInx - start_ColInx + 1;

                        int[] mergerNumArray = new int[excelMergerNum];
                        int tempIndex = 0;
                        for (int i = start_ColInx; i <= end_ColInx; i++)
                        {
                            mergerNumArray[tempIndex] = i;
                            tempIndex++;
                        }


                        var tempWordRowDatas = wordRowDTOs.Where(x => mergerNumArray.Any(t => t == x.ExcelCellPotion_ColIndex) && x.ExcelCellPotion_RowIndex == start_RowIndex).ToList();
                        if (tempWordRowDatas == null || tempWordRowDatas.Count == 0)
                        {
                            //需要合并的列，不在word表格中
                            continue;
                        }
                        if (tempWordRowDatas.Count == 1)
                        {
                            //需要合并的列，在word表格中,只有一列
                            continue;
                        }

                        int minVal = tempWordRowDatas.Min(x => x.WordColumnIndex);
                        int maxVal = tempWordRowDatas.Max(x => x.WordColumnIndex);

                        //开始 行和列
                        var tempStartRow = tempWordTableRows.ElementAt(start_RowIndex - 1);

                        var tempStartRowCell = tempStartRow.Descendants<TableCell>().ElementAt(minVal - 1);

                        //结束 行和列

                        var tempEndRow = tempWordTableRows.ElementAt(end_RowIndex - 1);

                        var tempEndRowCell = tempEndRow.Descendants<TableCell>().ElementAt(maxVal - 1);

                        if (tempStartRowCell != null && tempEndRowCell != null)
                        {
                            XmlTable.SetHorizontalMerge(tempStartRowCell, MergedCellValues.Restart);
                            for (int n = minVal; n <= maxVal - 1; n++)
                            {
                                var tempMergerCell = tempEndRow.Descendants<TableCell>().ElementAt(n);
                                XmlTable.SetHorizontalMerge(tempMergerCell, MergedCellValues.Continue);

                            }
                            // XmlTable.SetHorizontalMerge(tempEndRowCell, MergedCellValues.Continue);
                        }


                    }
                }
            }
            catch (Exception ex)
            {
                WriteLine($"合并单元格异常：{ex.Message}***{ex.StackTrace}***{ex.InnerException}");

            }

        }

        public bool IsTableTitle(TableRow tempRow)
        {
            if (tempRow == null)
            {
                return false;
            }
            bool isTitle = false;//true:标题行 ，false:数据行
            //判断纵向的结束行，是标题，还是数据行
            foreach (TableCell itemTableCell in tempRow.Descendants<TableCell>())
            {
                if (isTitle)
                {
                    break;
                }
                var paragraphs = itemTableCell.Descendants<Paragraph>();
                foreach (var paragraph in paragraphs)
                {
                    if (isTitle)
                    {
                        break;
                    }
                    var runs = paragraph.Descendants<Run>();
                    foreach (var run in runs)
                    {

                        var bold = run.Descendants<Bold>().FirstOrDefault();
                        if (bold != null)
                        {
                            isTitle = true;
                            break;
                        }
                    }
                }
            }
            return isTitle;
        }

        public HeadFootDTO GetHeadFootText(string wordFullPath)
        {
            WordprocessingDocument wd = null;
            if (File.Exists(wordFullPath))
            {
                wd = OpenDocumentPart(wordFullPath);
            }
            else
            {
                wd = CreateDocumentPart(wordFullPath);
                return new HeadFootDTO();
            }
            MainDocumentPart md = wd.MainDocumentPart;
            if (md == null)
            {
                return new HeadFootDTO();
            }

            HeadFootDTO headFootDTO = new HeadFootDTO();

            string headText = XmlHeaderFooter.GetHeadText(md);
            string footText = XmlHeaderFooter.GetFootText(md);
            headFootDTO.FooterText = footText;
            headFootDTO.HeaderText = headText;

            wd.Dispose();
            return headFootDTO;
        }

        public void AddHeader(MainDocumentPart mainDocPart, string paramHeader)
        {
            //var pageSize = GetBodyPageSize(mainDocPart.Document.Body);

            HeaderPart headerPart = XmlHeaderFooter.AddHeader(mainDocPart, paramHeader);
            AddHeadFootWaterMaskRelation(mainDocPart, headerPart);
        }

        private static void AddHeadFootWaterMaskRelation(MainDocumentPart mainDocPart, OpenXmlPart openXmlPart)
        {


            var secPrs = mainDocPart.Document.Descendants<SectionProperties>();
            if (secPrs.Count() == 0)
            {
                string rId = mainDocPart.GetIdOfPart(openXmlPart);
                if (openXmlPart is HeaderPart)
                {
                    Columns column = new Columns();
                    column.Space = "720";
                    column.ColumnCount = 1;
                    HeaderReference headerReference = new HeaderReference() { Id = rId, Type = HeaderFooterValues.Default };
                    /*设置 页眉，页脚和页面关系*/
                    SectionProperties sectPr = new SectionProperties(headerReference);
                    sectPr.Append(column);
                    mainDocPart.Document.Body.AppendChild<SectionProperties>(sectPr);
                    
                }
                else if (openXmlPart is FooterPart)
                {
                    Columns column = new Columns();
                    column.Space = "720";
                    column.ColumnCount = 1;

                    FooterReference newFooterReference = new FooterReference() { Id = rId, Type = HeaderFooterValues.Default };
                    /*设置 页眉，页脚和页面关系*/
                    SectionProperties sectPr = new SectionProperties(newFooterReference);
                    sectPr.Append(column);
                    mainDocPart.Document.Body.AppendChild<SectionProperties>(sectPr);
                }
                else
                {
                  
                }


               
            }
            else
            {
                foreach (SectionProperties item in secPrs)
                {
                    var columns = item.Descendants<Columns>();
                    if (columns != null && columns.Count() > 0)
                    {

                    }
                    else
                    {
                        Columns column = new Columns();
                        column.Space = "720";
                        column.ColumnCount = 1;
                        item.Append(column);
                    }

                }
            }

        }

        public void AddFooter(MainDocumentPart mainDocPart, string paramHeader)
        {
            //var pageSize = GetBodyPageSize(mainDocPart.Document.Body);

            FooterPart footerPart = XmlHeaderFooter.AddFooter(mainDocPart, paramHeader);
            AddHeadFootWaterMaskRelation(mainDocPart, footerPart);


        }
        public void AppendHeader(MainDocumentPart mainDocPart, string paramHeader)
        {
            var pageSize = GetBodyPageSize(mainDocPart.Document.Body);
            XmlHeaderFooter.AppendHeader(mainDocPart, paramHeader, pageSize);
        }

        #region 添加Word水印
        /// <summary>
        /// 添加Word水印
        /// </summary>
        /// <returns></returns>
        public bool AddWaterMark(MainDocumentPart mainPart, string waterText)
        {
            DocumentFormat.OpenXml.Vml.Shape topShape = CreateShape_Top(waterText);
            DocumentFormat.OpenXml.Wordprocessing.Picture topPicture = new DocumentFormat.OpenXml.Wordprocessing.Picture();
            topPicture.Append(topShape);

            DocumentFormat.OpenXml.Vml.Shape centerShape = CreateShape_Center(waterText);
            DocumentFormat.OpenXml.Wordprocessing.Picture centerPicture = new DocumentFormat.OpenXml.Wordprocessing.Picture();
            centerPicture.Append(centerShape);


            DocumentFormat.OpenXml.Vml.Shape bottomShape = CreateShape_Bottom(waterText);
            DocumentFormat.OpenXml.Wordprocessing.Picture bottomPicture = new DocumentFormat.OpenXml.Wordprocessing.Picture();
            bottomPicture.Append(bottomShape);
            HeaderPart headerPart = null;
            var headers = mainPart.HeaderParts;
            if (headers != null && headers.Count() > 0)
            {
                headerPart = headers.FirstOrDefault();
            }
            else
            {
                headerPart = XmlCall.XmlHeaderFooter.AddHeader(mainPart, "");
            }

            AddHeadFootWaterMaskRelation(mainPart, headerPart);


            //var secPrs = mainPart.Document.Descendants<SectionProperties>();
            //if (secPrs.Count() == 0)
            //{
            //    // PageSize pageSize = GetBodyPageSize(mainPart.Document.Body);
            //    Columns column = new Columns();
            //    column.Space = "720";
            //    column.ColumnCount = 1;
            //    /*设置 页眉，页脚和页面关系*/
            //    string rId = mainPart.GetIdOfPart(headerPart);
            //    SectionProperties sectPr = new SectionProperties(new HeaderReference() { Id = rId, Type = HeaderFooterValues.Default });
            //    // sectPr.Append(pageSize);
            //    sectPr.Append(column);
            //    mainPart.Document.Body.AppendChild<SectionProperties>(sectPr);
            //}
            //else
            //{
            //    //判断是否 有PageSize节点，没有则添加
            //    //string headerPartId = string.Empty;
            //    foreach (SectionProperties item in secPrs)
            //    {
            //        //var pageSize = item.Descendants<PageSize>();
            //        //if (pageSize != null && pageSize.Count() > 0)
            //        //{

            //        //}
            //        //else
            //        //{
            //        //设置页面尺寸
            //        //    PageSize itemPageSize = GetPortraitPageSize();
            //        //    item.Append(itemPageSize);
            //        //}
            //        var columns = item.Descendants<Columns>();
            //        if (columns != null && columns.Count() > 0)
            //        {

            //        }
            //        else
            //        {
            //            Columns column = new Columns();
            //            column.Space = "720";
            //            column.ColumnCount = 1;
            //            item.Append(column);
            //        }

            //    }
            //}

            Paragraph paragraph = new Paragraph();
            Run topRun = new Run();
            topRun.Append(topPicture);
            paragraph.Append(topRun);

            Run centerRun = new Run();
            centerRun.Append(centerPicture);
            paragraph.Append(centerRun);


            Run bottomRun = new Run();
            bottomRun.Append(bottomPicture);
            paragraph.Append(bottomRun);

            headerPart.Header.Append(paragraph);
            return true;
        }
        public DocumentFormat.OpenXml.Vml.Shape CreateShape_Top(string waterText)
        {
            // 创建一个Shape节点
            // 创建一个形状并设置其属性
            string pathstyle = "font-family:微软雅黑;font-size:60pt;v-same-letter-heights:f;v-text-align:center;";
            DocumentFormat.OpenXml.Vml.Shape shape = new DocumentFormat.OpenXml.Vml.Shape(
                // new DocumentFormat.OpenXml.Drawing.Extents() { Cx = 914400L, Cy = 165100L },
                new DocumentFormat.OpenXml.Vml.Stroke() { On = false },
                new DocumentFormat.OpenXml.Vml.Path(),
                new DocumentFormat.OpenXml.Vml.Fill() { On = true, Opacity = "32768f", FocusSize = "0,0" },
                new ImageData() { },
                new DocumentFormat.OpenXml.Vml.Office.Lock() { Extension = ExtensionHandlingBehaviorValues.Edit, Grouping = false, Rotation = false, TextLock = false, AspectRatio = true },
                new DocumentFormat.OpenXml.Vml.TextPath() { On = true, FitShape = true, FitPath = true, Trim = true, XScale = false, String = waterText, Style = pathstyle });
            shape.Adjustment = "10800";
            shape.FillColor = "#C0C0C0";
            shape.Filled = true;
            shape.Stroked = false;
            shape.CoordinateSize = "21600,21600";
            shape.Id = Guid.NewGuid().ToString().Replace("-", "");
            // shape.OptionalString = "_x0000_s4098";
            shape.OptionalNumber = 136;
            string style = "position:absolute;left:-4pt;height:60.35pt;width:277.35pt;mso-position-horizontal:left;mso-position-horizontal-relative:margin;mso-position-vertical:top;mso-position-vertical-relative:margin;rotation:-2949120f;z-index:-251656192;mso-width-relative:page;mso-height-relative:page;";
            shape.Style = style;
            return shape;
        }

        public DocumentFormat.OpenXml.Vml.Shape CreateShape_Center(string waterText)
        {
            // 创建一个Shape节点
            // 创建一个形状并设置其属性
            string pathstyle = "font-family:微软雅黑;font-size:60pt;v-same-letter-heights:f;v-text-align:center;";
            DocumentFormat.OpenXml.Vml.Shape shape = new DocumentFormat.OpenXml.Vml.Shape(
                // new DocumentFormat.OpenXml.Drawing.Extents() { Cx = 914400L, Cy = 165100L },
                new DocumentFormat.OpenXml.Vml.Stroke() { On = false },
                new DocumentFormat.OpenXml.Vml.Path(),
                new DocumentFormat.OpenXml.Vml.Fill() { On = true, Opacity = "32768f", FocusSize = "0,0" },
                new ImageData() { },
                new DocumentFormat.OpenXml.Vml.Office.Lock() { Extension = ExtensionHandlingBehaviorValues.Edit, Grouping = false, Rotation = false, TextLock = false, AspectRatio = true },
                new DocumentFormat.OpenXml.Vml.TextPath() { On = true, FitShape = true, FitPath = true, Trim = true, XScale = false, String = waterText, Style = pathstyle });
            shape.Adjustment = "10800";
            shape.FillColor = "#C0C0C0";
            shape.Filled = true;
            shape.Stroked = false;
            shape.CoordinateSize = "21600,21600";
            shape.Id = Guid.NewGuid().ToString().Replace("-", "");
            // shape.OptionalString = "_x0000_s4098";
            shape.OptionalNumber = 136;
            string style = "position:absolute;left:0pt;height:60.35pt;width:277.35pt;mso-position-horizontal:center;mso-position-horizontal-relative:margin;mso-position-vertical:center;mso-position-vertical-relative:margin;rotation:-2949120f;z-index:-251656192;mso-width-relative:page;mso-height-relative:page;";
            shape.Style = style;
            return shape;
        }

        public DocumentFormat.OpenXml.Vml.Shape CreateShape_Bottom(string waterText)
        {
            // 创建一个Shape节点
            // 创建一个形状并设置其属性
            string pathstyle = "font-family:微软雅黑;font-size:60pt;v-same-letter-heights:f;v-text-align:center;";
            DocumentFormat.OpenXml.Vml.Shape shape = new DocumentFormat.OpenXml.Vml.Shape(
                // new DocumentFormat.OpenXml.Drawing.Extents() { Cx = 914400L, Cy = 165100L },
                new DocumentFormat.OpenXml.Vml.Stroke() { On = false },
                new DocumentFormat.OpenXml.Vml.Path(),
                new DocumentFormat.OpenXml.Vml.Fill() { On = true, Opacity = "32768f", FocusSize = "0,0" },
                new ImageData() { },
                new DocumentFormat.OpenXml.Vml.Office.Lock() { Extension = ExtensionHandlingBehaviorValues.Edit, Grouping = false, Rotation = false, TextLock = false, AspectRatio = true },
                new DocumentFormat.OpenXml.Vml.TextPath() { On = true, FitShape = true, FitPath = true, Trim = true, XScale = false, String = waterText, Style = pathstyle });
            shape.Adjustment = "10800";
            shape.FillColor = "#C0C0C0";
            shape.Filled = true;
            shape.Stroked = false;
            shape.CoordinateSize = "21600,21600";
            shape.Id = Guid.NewGuid().ToString().Replace("-", "");
            // shape.OptionalString = "_x0000_s4098";
            shape.OptionalNumber = 136;
            string style = "position:absolute;left:0pt;height:60.35pt;width:277.35pt;mso-position-horizontal:right;mso-position-horizontal-relative:margin;mso-position-vertical:bottom;mso-position-vertical-relative:margin;rotation:-2949120f;z-index:-251656192;mso-width-relative:page;mso-height-relative:page;";
            shape.Style = style;
            return shape;
        }
        #endregion

        public bool ValidateWord(string filePath)
        {
            bool isWord = WordValidateDocument.ValidateWordDocument(filePath);
            return isWord;
        }


        private static readonly object objLock = new object();
        private static void WriteLine(string message)
        {
            string tempPath = CreateDirectory("Log");
            if (Monitor.TryEnter(objLock, 1000 * 60))
            {
                tempPath = tempPath + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                File.AppendAllText(tempPath, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + message + Environment.NewLine);
                Monitor.Exit(objLock);
            }
            else
            {
                tempPath = tempPath + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fs") + ".txt";
                File.AppendAllText(tempPath, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "发生死锁,牺牲一个锁,参数信息：" + message + Environment.NewLine);
            }
        }
        private static string CreateDirectory(string folderName)
        {
            string tempPath = "";
            string directory = System.Threading.Thread.GetDomain().BaseDirectory;
            if (directory.Contains("Debug"))
            {
                tempPath = directory.Replace("\\bin\\Debug\\", "") + "\\" + folderName + "\\";
            }
            else if (directory.Contains("Release"))
            {
                tempPath = directory.Replace("\\bin\\Release\\", "") + "\\" + folderName + "\\";
            }
            else
            {
                tempPath = directory.Replace("\\bin\\", "") + "\\" + folderName + "\\";
            }
            if (!Directory.Exists(tempPath))
            {
                Directory.CreateDirectory(tempPath);
            }
            return tempPath;
        }

    }
}
